package tw.com.hitevision.whiteboard.android.youtube.searchView;

import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.ListAdapter;
import androidx.recyclerview.widget.RecyclerView;

import com.bumptech.glide.load.resource.bitmap.DownsampleStrategy;
import com.bumptech.glide.signature.ObjectKey;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;

import tw.com.hitevision.whiteboard.android.R;
import tw.com.hitevision.whiteboard.android.util.GlideApp;
import tw.com.hitevision.whiteboard.android.util.GlideRequests;


public class YoutubeSearchAdapter extends ListAdapter<YoutubeSearchData, RecyclerView.ViewHolder> {

    private final String TAG = this.getClass().getSimpleName();
    private final Context context;
    private final List<YoutubeSearchData> youtubeSearchDataList;
    private final YoutubeSearchVideoListener listener;
    private GlideRequests videoThumbGlideRequests, channelThumbGlideRequests;

    public YoutubeSearchAdapter(Context context, List<YoutubeSearchData> videoList, YoutubeSearchVideoListener listener) {
        super(diffCallback);
        this.context = context;
        this.youtubeSearchDataList = videoList;
        this.listener = listener;
    }

    private static final DiffUtil.ItemCallback<YoutubeSearchData> diffCallback = new DiffUtil.ItemCallback<YoutubeSearchData>() {
        @Override
        public boolean areItemsTheSame(@NonNull YoutubeSearchData oldItem, @NonNull YoutubeSearchData newItem) {
            return oldItem.getVideoId().equals(newItem.getVideoId());
        }

        @Override
        public boolean areContentsTheSame(@NonNull YoutubeSearchData oldItem, @NonNull YoutubeSearchData newItem) {
            return oldItem.getVideoId().equals(newItem.getVideoId());
        }

        @Override
        public Object getChangePayload(@NonNull YoutubeSearchData oldItem, @NonNull YoutubeSearchData newItem) {
            return oldItem.getVideoId().equals(newItem.getVideoId());
        }
    };

    static class ViewHolder extends RecyclerView.ViewHolder {

        ViewHolder(@NonNull View itemView) {
            super(itemView);
            videoLayout = itemView.findViewById(R.id.youtube_search_recyclerView_item_layout);
            videoThumb = itemView.findViewById(R.id.youtube_search_recyclerView_item_thumb);
            channelThumb = itemView.findViewById(R.id.youtube_search_recyclerView_item_channel_thumb);
            videoTitle = itemView.findViewById(R.id.youtube_search_recyclerView_item_title);
            channelName = itemView.findViewById(R.id.youtube_search_recyclerView_item_channel_name);
            videoCountViewAndTime = itemView.findViewById(R.id.youtube_search_recyclerView_item_countViewAndTime);
            context = itemView.getContext();
        }

        private final Context context;
        private final View videoLayout;
        private final ImageView videoThumb;
        private final ImageView channelThumb;
        private final TextView videoTitle;
        private final TextView channelName;
        private final TextView videoCountViewAndTime;
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        videoThumbGlideRequests = GlideApp.with(context);
        channelThumbGlideRequests = GlideApp.with(context);
        return new ViewHolder(inflater.inflate(R.layout.menu_youtube_search_recycler_view_item, parent, false));
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        ((ViewHolder)holder).videoLayout.setOnClickListener(view -> listener.OnItemClick(youtubeSearchDataList.get(position)));

        videoThumbGlideRequests.load(youtubeSearchDataList.get(position).getVideoThumbURL())
                .downsample(DownsampleStrategy.CENTER_INSIDE)
                .signature(new ObjectKey(System.currentTimeMillis()))
                .centerInside()
                .into(((ViewHolder) holder).videoThumb);

        ((ViewHolder)holder).videoTitle.setText(youtubeSearchDataList.get(position).getVideoTitle());
        ((ViewHolder)holder).channelName.setText(youtubeSearchDataList.get(position).getVideoChannelTitle());
        if (youtubeSearchDataList.get(position).getVideoViewCount()!= null && youtubeSearchDataList.get(position).getVideoPublishedAt()!=null) {
            Log.d(TAG, "viewCount:" + youtubeSearchDataList.get(position).getVideoViewCount() + ", publishedAt:" + youtubeSearchDataList.get(position).getVideoPublishedAt());
        }
        ((ViewHolder)holder).videoCountViewAndTime.setText(getViewCountAndPublishedTime(youtubeSearchDataList.get(position).getVideoViewCount(), youtubeSearchDataList.get(position).getVideoPublishedAt()));
        if (youtubeSearchDataList.get(position).getVideoChannelThumbURL()!=null) {
            channelThumbGlideRequests.load(youtubeSearchDataList.get(position).getVideoChannelThumbURL())
                    .downsample(DownsampleStrategy.CENTER_INSIDE)
                    .signature(new ObjectKey(System.currentTimeMillis()))
                    .centerInside()
                    .into(((ViewHolder) holder).channelThumb);
        }
    }

    @Override
    public int getItemCount() {
        return youtubeSearchDataList.size();
    }

    @Override
    public void submitList(@Nullable List<YoutubeSearchData> videoList) {
        super.submitList(videoList);
        notifyDataSetChanged();
    }

    public interface YoutubeSearchVideoListener {
        void OnItemClick(YoutubeSearchData video);
    }

    private String getViewCountAndPublishedTime(String viewCount, String publishedTime) {
        Log.d(TAG, "getViewCountAndPublishedTime viewCount:" + viewCount + ", publishedTime:" + publishedTime);
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-M-dd'T'hh:mm:ss'Z'", Locale.US);
        dateFormat.setTimeZone(TimeZone.getDefault());
        String viewCountString = "";
        if (viewCount!=null) {
            try {
                viewCountString = String.valueOf(Long.parseLong(viewCount) / 1000);
                Date publishedDate = dateFormat.parse(publishedTime);
                Date currentDate = Calendar.getInstance().getTime();
                return viewCountString + "K views • " + getDifferenceDate(publishedDate, currentDate);
            } catch (ParseException e) {
                e.printStackTrace();
                return viewCountString + "huge views";
            }
        } else {
            return "";
        }
    }

    public String getDifferenceDate(Date startDate, Date endDate) {
        long different = endDate.getTime() - startDate.getTime();

        long secondsInMilli = 1000;
        long minutesInMilli = secondsInMilli * 60;
        long hoursInMilli = minutesInMilli * 60;
        long daysInMilli = hoursInMilli * 24;
        long weeksInMilli = daysInMilli * 7;
        long monthsInMilli = weeksInMilli * 4;
        long yearsInMilli = monthsInMilli * 12;

        long elapsedYears = different / yearsInMilli;
        different = different % yearsInMilli;

        long elapsedMonths = different / monthsInMilli;
        different = different % monthsInMilli;

        long elapsedWeeks = different / weeksInMilli;
        different = different % weeksInMilli;

        long elapsedDays = different / daysInMilli;
        different = different % daysInMilli;

        long elapsedHours = different / hoursInMilli;
        different = different % hoursInMilli;

        long elapsedMinutes = different / minutesInMilli;
        different = different % minutesInMilli;

        long elapsedSeconds = different / secondsInMilli;

//        Log.d(TAG, String.format("%d years, %d months, %d weeks, %d days, %d hours, %d minutes, %d seconds%n", elapsedYears, elapsedMonths, elapsedWeeks, elapsedDays, elapsedHours, elapsedMinutes, elapsedSeconds));

        if(elapsedYears == 0 && elapsedMonths == 0 && elapsedWeeks == 0 && elapsedDays == 0 && elapsedHours == 0 && elapsedMinutes == 0 && elapsedSeconds <= 59) {
            return "Just Now";
        } else if (elapsedYears == 0 && elapsedMonths == 0 && elapsedWeeks == 0 && elapsedDays == 0 && elapsedHours == 0 && elapsedMinutes < 60) {
            return elapsedMinutes + " minutes ago";
        } else if (elapsedYears == 0 && elapsedMonths == 0 && elapsedWeeks == 0 && elapsedDays == 0 && elapsedHours < 24) {
            return elapsedHours + " hours ago";
        } else if (elapsedYears == 0 && elapsedMonths == 0 && elapsedWeeks == 0 && elapsedDays < 7) {
            return elapsedDays + " days ago";
        } else if (elapsedYears == 0 && elapsedMonths == 0 && elapsedWeeks < 4) {
            return elapsedWeeks + " weeks ago";
        } else if (elapsedYears == 0 && elapsedMonths < 12) {
            return elapsedMonths + " mounts ago";
        } else {
            return elapsedYears + " years ago";
        }
    }
}
